#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/types.h>

#define SIZE 32
#define NUM 1024
#define SEP " "

//保存打散之后的命令行字符串
char *g_argv[SIZE];
//保存完整的命令行字符
char cmd_line[NUM];

//shell运行原理：通过让子进程执行命令，父进程等待&&解析命令
int main()
{
    //0.命令行解析器一定是一个常驻内存的进程，不退出
    while(1)
    {
        //打印出提示信息:[yxj@localhost myshell]#
        printf("[yxj@localhost myshell]# ");
        fflush(stdout);
        memset(cmd_line,'\0',sizeof cmd_line);
        //获取用户的输入：输入的是各种指令和选项（"ls -a -l -i"）
        if(fgets(cmd_line,sizeof cmd_line,stdin) == NULL)
        {
            continue;
        }
        //"ls -a -l -i\n\0"
        cmd_line[strlen(cmd_line)-1] = '\0';
        //printf("echo:%s\n",cmd_line);
        //3.命令行字符串解析："ls -a -l -i" -> "ls" "-a" "-l" "-i"
        g_argv[0] = strtok(cmd_line,SEP);//第一次调用要传入原始字符串
        int index = 1;
        if(strcmp(g_argv[0],"ls") == 0)
        {
            g_argv[index++] = "--color=auto";
        }
        if(strcmp(g_argv[0],"ll") == 0)
        {
            g_argv[0] = "ls";
            g_argv[index++] = "-l";
            g_argv[index++] = "--color=auto";
        }
        
        while(g_argv[index++] = strtok(NULL,SEP)); //第二次如果还要解析原始字符串，传入NULL
        //for 目的 debug
        //for(index = 0; g_argv[index]; index++)
        //{
           //printf("g_argv[%d]: %s\n",index,g_argv[index]);
        //}
        
        //4.内置命令,让父进程(shell)自己执行的命令,我们叫做内置命令,内建命令
        //内建命令本质就是shell中的一个函数调用
        if(strcmp(g_argv[0],"cd") == 0) //not child execute, father execute
        {
            if(g_argv[1] != NULL) chdir(g_argv[1]); //cd path, cd ...
            continue;
        }
        //5.for()
        pid_t id = fork();
        if(id == 0) // child
        {
            printf("功能让子进程进程的\n");
            execvp(g_argv[0],g_argv); //ls -a -l -i
            exit(1);
        }
        //father
        int status = 0;
        pid_t ret = waitpid(id,&status,0);
        if(ret > 0)
            printf("exit code:%d\n",WEXITSTATUS(status));
        
    }

}
